const { GameContent, GameRecord, User } = require('./model');
const { Op } = require('sequelize');

class GameDao {
  // 游戏内容相关操作
  
  // 创建游戏内容
  async createGameContent(contentData) {
    try {
      return await GameContent.create(contentData);
    } catch (error) {
      throw new Error(`创建游戏内容失败: ${error.message}`);
    }
  }

  // 获取游戏内容列表
  async getGameContents(options = {}) {
    try {
      const { page = 1, limit = 10, level, category, keyword } = options;
      const offset = (page - 1) * limit;
      
      const whereClause = { is_active: true };
      if (level) whereClause.level = level;
      if (category) whereClause.category = category;
      if (keyword) {
        whereClause[Op.or] = [
          { standard_text: { [Op.like]: `%${keyword}%` } },
          { pinyin: { [Op.like]: `%${keyword}%` } }
        ];
      }

      const { count, rows } = await GameContent.findAndCountAll({
        where: whereClause,
        order: [['usage_count', 'ASC'], ['created_at', 'DESC']],
        limit: parseInt(limit),
        offset: parseInt(offset)
      });

      return {
        contents: rows,
        total: count,
        page: parseInt(page),
        limit: parseInt(limit),
        totalPages: Math.ceil(count / limit)
      };
    } catch (error) {
      throw new Error(`获取游戏内容列表失败: ${error.message}`);
    }
  }

  // 随机获取游戏内容
  async getRandomGameContent(level = null, category = null) {
    try {
      const whereClause = { is_active: true };
      if (level) whereClause.level = level;
      if (category) whereClause.category = category;

      const contents = await GameContent.findAll({
        where: whereClause,
        order: GameContent.sequelize.random(),
        limit: 1
      });

      return contents.length > 0 ? contents[0] : null;
    } catch (error) {
      throw new Error(`获取随机游戏内容失败: ${error.message}`);
    }
  }

  // 随机获取多个游戏内容
  async getRandomGameContents(options = {}) {
    try {
      const { difficulty, category, limit = 10 } = options;
      const whereClause = { is_active: true };

      if (difficulty) whereClause.difficulty = difficulty;
      if (category) whereClause.category = category;

      const contents = await GameContent.findAll({
        where: whereClause,
        order: GameContent.sequelize.random(),
        limit: Math.min(parseInt(limit), 50) // 最多50个
      });

      return contents;
    } catch (error) {
      throw new Error(`获取随机游戏内容失败: ${error.message}`);
    }
  }

  // 获取每日挑战内容
  async getDailyChallengeContent(seed) {
    try {
      // 使用种子来确保每天的挑战内容是固定的
      const seedNumber = parseInt(seed) || Date.now();

      // 获取所有活跃的游戏内容
      const contents = await GameContent.findAll({
        where: { is_active: true },
        order: [['id', 'ASC']] // 使用固定排序确保结果一致
      });

      if (contents.length === 0) {
        return null;
      }

      // 使用种子选择固定的内容
      const index = seedNumber % contents.length;
      return contents[index];
    } catch (error) {
      throw new Error(`获取每日挑战内容失败: ${error.message}`);
    }
  }

  // 根据ID获取游戏内容
  async getGameContentById(id) {
    try {
      return await GameContent.findByPk(id);
    } catch (error) {
      throw new Error(`获取游戏内容失败: ${error.message}`);
    }
  }

  // 更新游戏内容
  async updateGameContent(id, updateData) {
    try {
      const [updatedRowsCount] = await GameContent.update(updateData, {
        where: { id }
      });
      
      if (updatedRowsCount === 0) {
        throw new Error('游戏内容不存在');
      }
      
      return await this.getGameContentById(id);
    } catch (error) {
      throw new Error(`更新游戏内容失败: ${error.message}`);
    }
  }

  // 增加使用次数
  async incrementUsageCount(id) {
    try {
      const content = await this.getGameContentById(id);
      if (!content) {
        throw new Error('游戏内容不存在');
      }

      return await this.updateGameContent(id, {
        usage_count: content.usage_count + 1
      });
    } catch (error) {
      throw new Error(`增加使用次数失败: ${error.message}`);
    }
  }

  // 删除游戏内容
  async deleteGameContent(id) {
    try {
      const deletedRowsCount = await GameContent.destroy({
        where: { id }
      });
      
      if (deletedRowsCount === 0) {
        throw new Error('游戏内容不存在');
      }
      
      return true;
    } catch (error) {
      throw new Error(`删除游戏内容失败: ${error.message}`);
    }
  }

  // 游戏记录相关操作

  // 创建游戏记录
  async createGameRecord(recordData) {
    try {
      // 增加游戏内容使用次数
      await this.incrementUsageCount(recordData.content_id);
      
      return await GameRecord.create(recordData);
    } catch (error) {
      throw new Error(`创建游戏记录失败: ${error.message}`);
    }
  }

  // 获取用户游戏记录
  async getUserGameRecords(userId, options = {}) {
    try {
      const { page = 1, limit = 10, startDate, endDate } = options;
      const offset = (page - 1) * limit;
      
      const whereClause = { user_id: userId };
      if (startDate && endDate) {
        whereClause.created_at = {
          [Op.between]: [startDate, endDate]
        };
      }

      const { count, rows } = await GameRecord.findAndCountAll({
        where: whereClause,
        include: [{
          model: GameContent,
          as: 'gameContent'
        }],
        order: [['created_at', 'DESC']],
        limit: parseInt(limit),
        offset: parseInt(offset)
      });

      return {
        records: rows,
        total: count,
        page: parseInt(page),
        limit: parseInt(limit),
        totalPages: Math.ceil(count / limit)
      };
    } catch (error) {
      throw new Error(`获取用户游戏记录失败: ${error.message}`);
    }
  }

  // 根据ID获取游戏记录
  async getGameRecordById(id) {
    try {
      return await GameRecord.findByPk(id, {
        include: [{
          model: GameContent,
          as: 'gameContent'
        }, {
          model: User,
          as: 'user',
          attributes: ['id', 'username', 'nickname', 'avatar']
        }]
      });
    } catch (error) {
      throw new Error(`获取游戏记录失败: ${error.message}`);
    }
  }

  // 更新游戏记录
  async updateGameRecord(id, updateData) {
    try {
      const [updatedRowsCount] = await GameRecord.update(updateData, {
        where: { id }
      });
      
      if (updatedRowsCount === 0) {
        throw new Error('游戏记录不存在');
      }
      
      return await this.getGameRecordById(id);
    } catch (error) {
      throw new Error(`更新游戏记录失败: ${error.message}`);
    }
  }

  // 删除游戏记录
  async deleteGameRecord(id) {
    try {
      const deletedRowsCount = await GameRecord.destroy({
        where: { id }
      });
      
      if (deletedRowsCount === 0) {
        throw new Error('游戏记录不存在');
      }
      
      return true;
    } catch (error) {
      throw new Error(`删除游戏记录失败: ${error.message}`);
    }
  }

  // 获取用户游戏统计
  async getUserGameStats(userId) {
    try {
      const totalGames = await GameRecord.count({
        where: { user_id: userId }
      });

      const stats = await GameRecord.findOne({
        where: { user_id: userId },
        attributes: [
          [GameRecord.sequelize.fn('AVG', GameRecord.sequelize.col('score')), 'avgScore'],
          [GameRecord.sequelize.fn('MAX', GameRecord.sequelize.col('score')), 'maxScore'],
          [GameRecord.sequelize.fn('AVG', GameRecord.sequelize.col('similarity')), 'avgSimilarity']
        ],
        raw: true
      });

      return {
        totalGames,
        averageScore: parseFloat(stats?.avgScore || 0).toFixed(2),
        bestScore: parseFloat(stats?.maxScore || 0).toFixed(2),
        averageSimilarity: parseFloat(stats?.avgSimilarity || 0).toFixed(2)
      };
    } catch (error) {
      throw new Error(`获取用户游戏统计失败: ${error.message}`);
    }
  }

  // 获取游戏排行榜
  async getGameLeaderboard(options = {}) {
    try {
      const { limit = 10, period = 'all' } = options;
      
      let whereClause = {};
      if (period === 'week') {
        const weekAgo = new Date();
        weekAgo.setDate(weekAgo.getDate() - 7);
        whereClause.created_at = { [Op.gte]: weekAgo };
      } else if (period === 'month') {
        const monthAgo = new Date();
        monthAgo.setMonth(monthAgo.getMonth() - 1);
        whereClause.created_at = { [Op.gte]: monthAgo };
      }

      const leaderboard = await GameRecord.findAll({
        where: whereClause,
        attributes: [
          'user_id',
          [GameRecord.sequelize.fn('AVG', GameRecord.sequelize.col('score')), 'avgScore'],
          [GameRecord.sequelize.fn('COUNT', GameRecord.sequelize.col('id')), 'gameCount']
        ],
        include: [{
          model: User,
          as: 'user',
          attributes: ['id', 'username', 'nickname', 'avatar']
        }],
        group: ['user_id'],
        order: [[GameRecord.sequelize.literal('avgScore'), 'DESC']],
        limit: parseInt(limit)
      });

      return leaderboard;
    } catch (error) {
      throw new Error(`获取游戏排行榜失败: ${error.message}`);
    }
  }
}

module.exports = new GameDao();
